package com.syscom.server.qd.cacheManager;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;

import org.apache.log4j.Logger;

import com.syscom.server.cache.safeCache.vo.RuleQtaHandleCacheVo;

public class DrawBackThreadLockManager {
	private static DrawBackThreadLockManager instance = new DrawBackThreadLockManager();
	
	// 沒SYNC 不應該有任何GET以外的動作
	private Map<String, Object> mapThreadBlock = new Hashtable<String, Object>();
	
	private Map<String, HashSet<String>> mapServerIdSet = new Hashtable<String, HashSet<String>>();
	
	private static Logger mLogger = Logger.getLogger(DrawBackThreadLockManager.class.getName());
	
	public static DrawBackThreadLockManager getInstance() {
		return instance;
	}
	
	private DrawBackThreadLockManager() {
		// ruleid prodid
		String[] sKeys = RuleQtaCacheManager.getInstance().getAllRuleQtaKeyString();
		
		for(int i = 0 ; i < sKeys.length ; i++) {
			mapThreadBlock.put(sKeys[i], new Object());
		}
	}
	
	public void lockThread(String sServerId, int iRuleId, String sProdId) {
		String sKey = RuleQtaHandleCacheVo.getKeyString(iRuleId, sProdId);
		
		if(mapThreadBlock.containsKey(sKey)) {
			long lTimeout = GlobalConfigManager.getInstance().getDrawBackTimeout();
			
			Object obj = mapThreadBlock.get(sKey);
			
			String[] serverIds = GlobalConfigManager.getInstance().getServerIdList();
			
			HashSet<String> set = new HashSet<String>();
			for(int i = 0 ; i < serverIds.length ; i++) {
				set.add(serverIds[i]);
			}
			// 移除自己的 自己不用DrawBack
			set.remove(sServerId);
			
			synchronized(mapServerIdSet) {
				mapServerIdSet.put(sKey, set);
			}
			
			synchronized(obj) {
				try {
					obj.wait(lTimeout);
				} catch (InterruptedException ex) {
					mLogger.error(ex.getMessage());
					ex.printStackTrace();
				}
			}
		}
	}
	
	public void drawBackServerRecord(String sServerId, int iRuleId, String sProdId) {
		String sKey = RuleQtaHandleCacheVo.getKeyString(iRuleId, sProdId);
		
		synchronized(mapServerIdSet) {
			HashSet<String> set = mapServerIdSet.get(sKey);
			set.remove(sServerId);
			
			if(set.size() == 0) {
				freeThreadLock(iRuleId, sProdId);
			}
		}
	}
	
	private void freeThreadLock(int iRuleId, String sProdId) {
		String sKey = RuleQtaHandleCacheVo.getKeyString(iRuleId, sProdId);
		
		if(mapThreadBlock.containsKey(sKey)) {
			Object obj = mapThreadBlock.get(sKey);

			mLogger.debug("All Server DrawBack Quota. RuleId:[" + iRuleId + "], ProdId:[" + sProdId + "]");
			synchronized(obj) {
				obj.notifyAll();
			}
		}
	}
}
